import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
import { KEEP_KEY } from '../constants/decorator.constant';
import { ResponseResultDto } from 'src/common/dtos/result-response.dto';

/**
 * 响应格式统一拦截器
 * 该拦截器用于统一处理所有响应的格式
 */
@Injectable()
export class ResponseInterceptor implements NestInterceptor {
  constructor(private readonly reflector: Reflector) {}

  /**
   * 拦截请求并处理响应
   * @param context - 执行上下文，包含请求和响应信息
   * @param next - 处理程序的调用处理器
   * @returns {Observable<any>} - 返回处理后的响应
   */
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      map((data) => {
        // 获取路由上是否标记了 @Keep() 装饰器
        const keep = this.reflector.getAllAndOverride<boolean>(KEEP_KEY, [
          context.getHandler(), // 获取方法级别的元数据
          context.getClass() // 获取类级别的元数据
        ]);

        // 如果路由标记为保留，直接返回原始数据
        if (keep) return data;

        // 如果返回的数据是 ResponseResultDto 实例，直接返回
        // console.log('data :>> ', data);
        // console.log('ResponseResultDto :>> ', ResponseResultDto);
        // console.log('data instanceof ResponseResultDto :>> ', data instanceof ResponseResultDto);
        if (data instanceof ResponseResultDto) return data;

        // 获取HTTP响应对象
        const response = context.switchToHttp().getResponse();
        // 设置响应头
        response.header('Content-Type', 'application/json; charset=utf-8');
        // 返回统一格式的响应
        // console.log('ResponseResultDto.success(data) :>> ', ResponseResultDto.success(data));
        return ResponseResultDto.success(data);
      })
    );
  }
}
